from peewee import *


class _Proxy(Proxy):
    """
        add a method to initialize database from a uri
    """
    def initialize_from_uri(self, uri, check=True):
        import re
        expr = r'(?P<driver>\w+)://((?P<username>[\w|\d]+):(?P<passwd>[\w|\d]+)@' \
               r'(?P<host>[\w|\d]+)(:(?P<port>\d+))?)?/(?P<dbname>.+)'
        result = re.match(expr, uri)
        if result is None:
            raise RuntimeError('DATABASE URI is not valid. Please check your settings')

        result = result.groupdict()
        driver = result['driver']
        username = result['username']
        passwd = result['passwd']
        host = result['host']
        port = result['port']
        dbname = result['dbname']

        if driver == 'sqlite':
            assert username is None and passwd is None
            assert host is None and port is None
            assert dbname is not None
            self.initialize(SqliteDatabase(dbname))
        elif driver == 'mysql':
            assert username is not None and passwd is not None
            assert host is not None and dbname is not None
            port = int(port) if port else 3306
            self.initialize(MySQLDatabase(dbname, host=host, port=port, user=username, passwd=passwd))
        else:
            raise RuntimeError('%s are not supported' % driver)

        if check is True:
            try:
                db.connect()
            except:
                raise RuntimeError("Couldn't connect to the database. Maybe you should create it first")


db = _Proxy()


class BaseModel(Model):
    class Meta:
        database = db


class Artist(BaseModel):
    pixiv_id = IntegerField(unique=True)
    name = CharField()


class Illustration(BaseModel):
    illust_id = IntegerField(unique=True)
    title = CharField()
    url = CharField()
    artist = ForeignKeyField(Artist, related_name='illustrations')
    upload_timestamp = IntegerField()
    page_count = IntegerField()


class DailyRank(BaseModel):
    illustration = ForeignKeyField(Illustration, related_name='daily_ranks')
    rank = IntegerField()
    date = DateField()

    class Meta:
        indexes = (
            # create a unique on illustration/rank/date
            (('illustration', 'rank', 'date'), True),
        )


class Page(BaseModel):
    mode = CharField()
    p = IntegerField()
    date = DateField()

    class Meta:
        indexes = (
            # create a unique on mode/p/date
            (('mode', 'p', 'date'), True),
        )